<script setup lang="ts">
import { ref, computed, reactive, watch } from 'vue'
import type { FormInst, FormItemRule, FormRules } from 'naive-ui'
import { $t } from '@/locales'
import { userGenderOptions } from '@/constants/business'

const { add, find, update } = useUser()
const { loading: loading, startLoading, endLoading } = useLoading(false)

defineOptions({ name: 'UserOperateModal' })

interface Props {
  visible: boolean
  type?: 'add' | 'edit'
  id?: number
  load: Function
}

interface Emits {
  (e: 'update:visible', visible: boolean): void
  (e: 'load'): void
}

const emit = defineEmits<Emits>()
const props = withDefaults(defineProps<Props>(), {
  type: 'add',
})

const defaultModel = (): UserModel => ({
  username: '',
  mobile: '',
  name: '',
  real_name: '',
  gender: 0,
  email: '',
  id: 0,
  avatar: null,
  is_super_admin: 0,
})

const formModel = ref<UserModel>(defaultModel())

watch(
  () => props.visible,
  async (newValue) => {
    if (newValue) {
      if (props.type === 'edit' && props.id) {
        formModel.value = await find(props.id)
      } else {
        formModel.value = defaultModel()
      }
    }
  },
)

const formRef = ref<FormInst | null>(null)

const modalTitle = computed(() => {
  const titles: Record<'add' | 'edit', string> = {
    add: $t('page.system.user.addUser'),
    edit: $t('page.system.user.editUser'),
  }
  return titles[props.type]
})

const rules: FormRules = {
  name: {
    required: true,
    message: $t('page.system.user.form.name'),
    trigger: 'input',
  },
  real_name: {
    required: true,
    message: $t('page.system.user.form.realName'),
    trigger: 'input',
  },
  mobile: {
    required: true,
    message: $t('page.system.user.form.mobile'),
    trigger: 'input',
  },
  email: [
    {
      required: true,
      message: $t('page.system.user.form.email'),
      trigger: 'input',
    },
    {
      type: 'email',
      message: $t('page.system.user.form.emailRule'),
      trigger: 'input',
    },
  ],
  gender: {
    required: true,
    message: $t('page.system.user.form.gender'),
    trigger: 'input',
  },
}

const handleModalClose = (visible: boolean) => {
  emit('update:visible', visible)
}

const handleModalConfirm = async () => {
  // 表单验证
  const valid = await formRef.value?.validate((errors) => !errors)
  if (!valid) return

  startLoading()
  try {
    // 调用新增/编辑接口
    const { success } =
      props.type === 'add' ? await add(formModel.value) : await update(formModel.value)

    // 接口调用成功后，刷新表格数据
    if (success) {
      handleModalClose(false)
      emit('load')
    }
  } finally {
    endLoading()
  }
}
</script>

<template>
  <ad-modal
    :visible="visible"
    :title="modalTitle"
    :loading="loading"
    @update:visible="handleModalClose"
    @confirm="handleModalConfirm"
    class="w-2xl!"
  >
    <n-form ref="formRef" :label-width="80" :model="formModel" :rules="rules">
      <n-grid :cols="24" :x-gap="24">
        <n-form-item-gi :span="12" :label="$t('page.system.user.username')" path="email">
          <NInput
            v-model:value="formModel.username"
            :placeholder="$t('page.system.user.form.username')"
          />
        </n-form-item-gi>
        <n-form-item-gi :span="12" :label="$t('page.system.user.email')" path="email">
          <NInput
            v-model:value="formModel.email"
            :placeholder="$t('page.system.user.form.email')"
          />
        </n-form-item-gi>
        <n-form-item-gi :span="12" :label="$t('page.system.user.name')" path="name">
          <NInput v-model:value="formModel.name" :placeholder="$t('page.system.user.form.name')" />
        </n-form-item-gi>
        <n-form-item-gi :span="12" :label="$t('page.system.user.real_name')" path="real_name">
          <NInput
            v-model:value="formModel.real_name"
            :placeholder="$t('page.system.user.form.realName')"
          />
        </n-form-item-gi>
        <n-form-item-gi :span="12" :label="$t('page.system.user.mobile')" path="mobile">
          <NInput
            v-model:value="formModel.mobile"
            :placeholder="$t('page.system.user.form.mobile')"
          />
        </n-form-item-gi>
        <n-form-item-gi :span="12" :label="$t('page.system.user.form.gender')" path="gender">
          <n-radio-group v-model:value="formModel.gender">
            <n-radio
              v-for="item in userGenderOptions"
              :key="item.value"
              :value="item.value"
              :label="$t(item.label)"
            />
          </n-radio-group>
        </n-form-item-gi>
      </n-grid>
    </n-form>
  </ad-modal>
</template>

<style lang="scss" scoped></style>
